#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    BaseRestEditor(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    selectId=0;
    listModel=new QStringListModel(this);
    ui->listView->setModel(listModel);

    tableModel=new TableModel(this);
    ui->tableView->setModel(tableModel);

    createMenu();
    move(200,100);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::updateMenu()
{
    if(!menu->isEmpty())
    {
        menu->disconnect();
        menu->clear();
    }

    menu->addAction(QStringLiteral("添加... (F1)"),this,&Widget::newItem);
    menu->addSeparator();
    if(selectId != ID_VERSION)
    {
        menu->addAction(QStringLiteral("编辑... (F2)"),this,&Widget::editItem);
        menu->addSeparator();
    }

    if(selectId == ID_DEMAND)
    {
        menu->addAction(QStringLiteral("【已完成】"),this,&Widget::do_changeFinish);
        menu->addAction(QStringLiteral("【已取消】"),this,&Widget::do_changeFinish);
        menu->addSeparator();
    }

    menu->addAction(QStringLiteral("更新列表 (F4)"),this,&Widget::updateListView);
    menu->addAction(QStringLiteral("更新视图 (F5)"),this,&Widget::updateTableView);
}

void Widget::do_changeFinish()
{
    if(selectId != ID_DEMAND)
        return;

    QModelIndex index=ui->tableView->currentIndex();
    if(index.isValid())
    {
        int id=sp_fetchId(index);

        QJsonObject obj;
        obj.insert("id",id);
        obj.insert("addition","已完成");

        onUpdateItem(obj);
        delayUpdateView();
    }
}

void Widget::do_changeCancel()
{
    if(selectId != ID_DEMAND)
        return;

    QModelIndex index=ui->tableView->currentIndex();
    if(index.isValid())
    {
        int id=sp_fetchId(index);
        QJsonObject obj;
        obj.insert("id",id);
        obj.insert("addition","已取消");

        onUpdateItem(obj);
        delayUpdateView();
    }
}

void Widget::customKeyEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_F1:
        newItem();
        break;
    case Qt::Key_F2:
        editItem();
        break;
    case Qt::Key_F4:
        updateListView();
        break;
    case Qt::Key_F5:
        updateTableView();
        break;
    }
}

void Widget::updateListView()
{
    if(selectId == ID_CHANGLOG)
    {
        QString url=baseUrl_ + "get_entries";
        emit get(url);
        tableModel->clear();
    }
}

void Widget::updateTableView()
{
    tableModel->clear();

    QString url;
    switch (selectId) {
    case ID_CHANGLOG:
        if(selectEntry.isEmpty())
            return;

        url=baseUrl_ + "by_entry/" + selectEntry;
        break;
    case ID_VERSION:
        url=baseUrl_ + "get_all";
        break;
    case ID_DEMAND:
        url=baseUrl_ + "get_detail";
        break;
    }

    if(!url.isEmpty())
        emit get(url);
}

void Widget::delayUpdateView()
{
    QEventLoop loop;
    QTimer::singleShot(200,&loop,&QEventLoop::quit);
    loop.exec();
    updateTableView();
}

void Widget::onReceivedObject(const QJsonObject &object)
{
    if(!object.contains("entry") || object.value("entry").toString() != entry_)
        return;

    setWindowTitle(_title);
    switch (selectId) {
    case ID_CHANGLOG:
        processChangeLog(object);
        break;
    case ID_VERSION:
        processVersion(object);
        break;
    case ID_DEMAND:
        processDemand(object);
        break;
    }
}

void Widget::processChangeLog(const QJsonObject &object)
{
    if(object.contains("entries"))
    {
        QJsonArray array=object.value("entries").toArray();
        if(array.isEmpty())
            return;

        entries=Piv(array).getStringList();
        if(!entries.isEmpty())
            listModel->setStringList(entries);
    }
    else if(object.contains("detail"))
    {
        QJsonArray array=object.value("detail").toArray();
        if(array.isEmpty())
            return;

        tableModel->setArray(array,
                             changeLogColumns,
                             changeLogColumnHeaders);
        ui->tableView->hideColumn(0);

        if(tableModel->rowCount() > 0)
            ui->tableView->resizeRowsToContents();
    }
}

void Widget::processVersion(const QJsonObject &object)
{
    if(object.contains("_all"))
    {
        QJsonArray array=object.value("_all").toArray();
        if(array.isEmpty())
            return;

        Piv piv(array);
        versionList=piv.getStringList("entry");

        tableModel->setArray(array,
                             versionColumns,
                             versionColumnHeaders);
    }
}

void Widget::processDemand(const QJsonObject &object)
{
    if(object.contains("detail"))
    {
        QJsonArray array=object.value("detail").toArray();
        if(array.isEmpty())
            return;

        tableModel->setArray(array,
                             demandColumns,
                             demandColumnHeaders);
        ui->tableView->hideColumn(0);

        if(tableModel->rowCount() > 0)
            ui->tableView->resizeRowsToContents();
    }
}

void Widget::newItem()
{
    switch (selectId) {
    case ID_CHANGLOG:
    {
        CL_AddItem addItem(this,entries);
        QModelIndex index=tableModel->index(0,2);
        if(tableModel->rowCount() != 0 && index.isValid())
        {
            int version=tableModel->data(index).toInt() + 1;
            addItem.setEntry(selectEntry,version);
        }
        else
            addItem.setEntry(selectEntry);
        connect(&addItem,&CL_AddItem::addItem,
                this,&Widget::onAddItem);
        if(addItem.exec() == QDialog::Accepted)
            delayUpdateView();
    }
        break;
    case ID_VERSION:
    {
        V_AddItem addItem;
        connect(&addItem,&V_AddItem::addItem,
                this,&Widget::onAddItem);
        if(addItem.exec() == QDialog::Accepted)
            delayUpdateView();
    }
        break;
    case ID_DEMAND:
    {
        D_AddItem addItem;
        connect(&addItem,&D_AddItem::addItem,
                this,&Widget::onAddItem);
        if(addItem.exec() == QDialog::Accepted)
            delayUpdateView();
    }
        break;
    }
}

void Widget::editItem()
{
    QModelIndex index=ui->tableView->currentIndex();
    if(!index.isValid())
        return;

    int id=sp_fetchId(index);
    if(selectId == ID_CHANGLOG)
    {
        int version=sp_fetchData(index,
                                 changeLogColumns.indexOf("version"))
                .toInt();
        QString detail=sp_fetchString(index,
                                      changeLogColumns.indexOf("detail"));

        CL_AddItem addItem(this,entries);
        addItem.setItem(id,selectEntry,version,detail);
        connect(&addItem,&CL_AddItem::updateItem,this,&Widget::onUpdateItem);
        if(addItem.exec() == QDialog::Accepted)
            delayUpdateView();
    }
    else if(selectId == ID_DEMAND)
    {
        QString label=sp_fetchString(index,
                                     demandColumns.indexOf("label"));
        QString detail=sp_fetchString(index,
                                      demandColumns.indexOf("detail"));

        D_AddItem addItem;
        addItem.setItem(id,label,detail);
        connect(&addItem,&D_AddItem::updateItem,this,&Widget::onUpdateItem);
        if(addItem.exec() == QDialog::Accepted)
            delayUpdateView();
    }
}

void Widget::onAddItem(const QJsonObject &obj)
{
    if(selectId == ID_VERSION)
    {
        QString entry=obj.value("entry").toString();
        if(versionList.contains(entry))
        {
            onUpdateItem(obj);
            return;
        }
    }

    QString url=baseUrl_ + "insert";
    emit post(url,QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

void Widget::onUpdateItem(const QJsonObject &obj)
{
    QString url=baseUrl_ + "update";
    emit post(url,QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

void Widget::on_listView_doubleClicked(const QModelIndex &index)
{
    if(index.isValid())
    {
        selectEntry=index.data().toString();
        updateTableView();
    }
}

void Widget::on_btn_changeLog_clicked()
{
    selectId=ID_CHANGLOG;
    entry_=T_CHANGELOG;
    baseUrl_=URL_CHANGELOG;
    _title=TLE_CHANGELOG;

    if(!ui->listView->isEnabled())
        ui->listView->setEnabled(true);

    updateListView();
}

void Widget::on_btn_version_clicked()
{
    selectId=ID_VERSION;
    entry_=T_VERSION;
    baseUrl_=URL_VERSION;
    _title=TLE_VERSION;

    if(listModel->rowCount() != 0)
        listModel->setStringList(QStringList());

    if(ui->listView->isEnabled())
        ui->listView->setEnabled(false);

    updateTableView();
}

void Widget::on_btn_demand_clicked()
{
    selectId=ID_DEMAND;
    entry_=T_DEMAND;
    baseUrl_=URL_DEMAND;
    _title=TLE_DEMAND;

    if(listModel->rowCount() != 0)
        listModel->setStringList(QStringList());

    if(ui->listView->isEnabled())
        ui->listView->setEnabled(false);

    updateTableView();
}
